#!/usr/bin/python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

import socket
import traceback
from gi.repository import GLib
from ..wrt_param import WrtConst


class DnsApiServer:

    def __init__(self, dnsServer, socketFile):
        try:
            self._srv = dnsServer
            self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
            self._sock.bind(socketFile)
            self._sourceId = GLib.io_add_watch(self._sock, GLib.IO_IN, self.onRecv)
        except Exception:
            self.dispose()
            raise

    def dispose(self):
        if self._sourceId is not None:
            GLib.source_remove(self._sourceId)
        if self._sock is not None:
            self._sock.close()
        if self.srv is not None:
            self._srv.abort_all_request(self)

    def onRecv(self, source, cb_condition):
        try:
            data, addr = source.recvfrom(8192)
            try:
                self._srv.request(self, data, lambda x: self.onRequestCallback(addr, x))
            except Exception:
                # absorb exception raised by upper layer function, FIXME
                print("upper layer exception")
                traceback.print_exc()
                raise
        except Exception:
            print("excp IO_IN, %d" % (cb_condition & GLib.IO_IN))               # FIXME
            print("excp IO_PRI, %d" % (cb_condition & GLib.IO_PRI))
            print("excp IO_ERR, %d" % (cb_condition & GLib.IO_ERR))
            print("excp IO_HUP, %d" % (cb_condition & GLib.IO_HUP))
            print("excp IO_NVAL, %d" % (cb_condition & GLib.IO_NVAL))
            traceback.print_exc()
        finally:
            return True

    def onRequestCallback(self, sourceAddr, replyData):
        self._sock.sendto(replyData, sourceAddr)
